package com.lmf.Stack;


import java.util.Scanner;

/**
 * 模拟实现栈：利用数组
 */
public class ArrayStackDemo {

    public static void main(String [] args){
        //创建一个栈:长度为5
        ArrayStack stack = new ArrayStack(5);

        //手动测试模式：
        //添加数据进栈
        stack.push(1);
        stack.push(2);
        stack.push(3);
        stack.push(4);
        //遍历打印
        stack.list();
        System.out.println("------------------");
        //取出数据
        stack.pop();
        stack.pop();
        stack.list();
        System.out.println("------------------");

        //测试方法二：用户菜单模式
        test(stack);


    }
    //用户菜单模式：测试栈
    public static void test(ArrayStack stack){
        //创建扫描器对象
        Scanner scanner = new Scanner(System.in);
        //创建一个变量，作为接收用户输入的选择
        String  key = null;
        //打一个标志，控制while循环的开始与结束
        boolean flag = true;
        //创建一个菜单
        while (flag){
            System.out.println(" a(push):将数据添加进栈 ");
            System.out.println(" p(pop):从栈中弹出一个数据 ");
            System.out.println(" l(list):将栈中数据遍历打印 ");
            System.out.println(" e(exit):退出程序 ");
            System.out.println("请输入你的选择：注意输错，将会直接退出程序！！！");
            key = scanner.next();
            //业务逻辑处理
            switch (key){
                case "a" :
                    System.out.println("请输入一个数：");
                    String value = scanner.next();
                    stack.push(Integer.parseInt(value));
                    break;
                case "p" :
                    try {
                        stack.pop();
                    } catch (Exception e) {
                        System.out.println(e.getMessage());
                    }
                    break;
                case "l" :
                    try {
                        stack.list();
                    } catch (Exception e) {
                        System.out.println(e.getMessage());
                    }
                    break;
                case "e" :
                    scanner.close();
                    flag = false;
                    System.out.println("退出程序！");
//                    return;
                    break;
                default:
                    scanner.close();
                    flag = false;
                    System.out.println("输入格式不正确，已默认退出程序！");
                    break;
            }
        }
    }
}

//创建一个利用数组实现的栈
class ArrayStack{
    //数组最大空间
    private int maxSize;
    //创建一个数组
    private int[] stack;
    //创建一个指向数组顶端的指针
    private int top = -1;   //表示栈顶 初始化为-1

    //创建构造方法：初始化参数
    public ArrayStack(int maxSize) {
        this.maxSize = maxSize;
        this.stack = new int[this.maxSize];
    }

    //判断栈满的方法
    public boolean isFull(){
        return top == maxSize-1;
    }

    //判断栈空的方法
    public boolean isEmpty(){
        return top == -1;
    }

    //定义入栈操作
    public void push(int num){
        //先判断栈是否已满
        if (this.isFull()) {
            System.out.println("栈空间已满，不能再添加数据！");
            return;
        }
        top++;
        stack[top] = num;
    }

    //定义出栈操作:必须满足“先入后出”规律
    public int pop(){
        //先判断栈是否为空
        if (this.isEmpty()) {
            throw new RuntimeException("栈空，没有可以取出的数据！");
        }
        //栈若不为空
        int value = stack[top];
        top--;
        return value;
    }

    // 显示栈信息(遍历栈) 遍历时 需要从栈顶开始显示
    public void list(){
        //先判断栈是否为空
        if (this.isEmpty()) {
            throw new RuntimeException("栈为空，没有可以遍历的数据！");
        }
        //创建辅助指针，不能直接使用原头指针，否则遍历过后，原头指针就不再指向数组顶端了
        int temp = top;
        //若不为空，遍历打印
        System.out.println("栈中数据如下：");
        while (temp >= 0){
            System.out.printf("stack[%d]\n",stack[temp]);
            temp--;
        }
    }

}